Java 26-Day Course - Day 16: Collections - Set and Map

Day 16: Collections - Set and Map

Set is a collection that does not allow duplicates, and Map stores data as key-value pairs. A Set is like a bag of marbles where you keep only one of each color, while a Map is like a dictionary where you look up definitions (values) by words (keys).

HashSet and TreeSet

Two implementations for handling duplicate-free sets.

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

public class SetExample {
    public static void main(String[] args) {
        // HashSet: no order guarantee, O(1) access
        Set<String> hashSet = new HashSet<>();
        hashSet.add("Java");
        hashSet.add("Python");
        hashSet.add("Go");
        hashSet.add("Java");  // Duplicate! Not added
        hashSet.add("Rust");

        System.out.println("HashSet: " + hashSet);        // Unordered
        System.out.println("Size: " + hashSet.size());     // 4 (duplicates excluded)
        System.out.println("Contains Java? " + hashSet.contains("Java")); // true

        // LinkedHashSet: maintains insertion order
        Set<String> linkedSet = new LinkedHashSet<>();
        linkedSet.add("First");
        linkedSet.add("Second");
        linkedSet.add("Third");
        System.out.println("LinkedHashSet: " + linkedSet); // Insertion order maintained

        // TreeSet: auto-sorted (ascending)
        Set<Integer> treeSet = new TreeSet<>();
        treeSet.add(42);
        treeSet.add(15);
        treeSet.add(8);
        treeSet.add(99);
        treeSet.add(23);
        System.out.println("TreeSet: " + treeSet); // [8, 15, 23, 42, 99]

        // Set operations
        Set<String> setA = new HashSet<>(Set.of("Java", "Python", "Go"));
        Set<String> setB = new HashSet<>(Set.of("Python", "Rust", "Go"));

        // Union
        Set<String> union = new HashSet<>(setA);
        union.addAll(setB);
        System.out.println("Union: " + union);

        // Intersection
        Set<String> intersection = new HashSet<>(setA);
        intersection.retainAll(setB);
        System.out.println("Intersection: " + intersection);

        // Difference
        Set<String> difference = new HashSet<>(setA);
        difference.removeAll(setB);
        System.out.println("Difference: " + difference);
    }
}

HashMap Basics

The most commonly used Map implementation that stores key-value pairs.

import java.util.HashMap;
import java.util.Map;

public class HashMapBasic {
    public static void main(String[] args) {
        Map<String, Integer> scores = new HashMap<>();

        // Add entries
        scores.put("Alice", 85);
        scores.put("Bob", 92);
        scores.put("Charlie", 78);
        scores.put("Diana", 95);

        // Retrieve
        System.out.println("Alice's score: " + scores.get("Alice"));       // 85
        System.out.println("Missing key: " + scores.get("Eve"));            // null
        System.out.println("Default: " + scores.getOrDefault("Eve", 0));    // 0

        // Update (put with same key overwrites the value)
        scores.put("Alice", 90);
        System.out.println("After update: " + scores.get("Alice")); // 90

        // Contains check
        System.out.println("Has key? " + scores.containsKey("Bob"));      // true
        System.out.println("Has value? " + scores.containsValue(78));      // true

        // Remove
        scores.remove("Charlie");
        System.out.println("Size: " + scores.size()); // 3

        // Iteration methods
        // 1. entrySet (most efficient when both key and value are needed)
        for (Map.Entry<String, Integer> entry : scores.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }

        // 2. keySet
        for (String name : scores.keySet()) {
            System.out.println(name + " -> " + scores.get(name));
        }

        // 3. forEach + lambda
        scores.forEach((name, score) ->
            System.out.println(name + " = " + score));
    }
}

Advanced Map Usage

Convenient methods added since Java 8.

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class MapAdvanced {
    public static void main(String[] args) {
        // Word frequency counting
        String text = "Java is an object-oriented language Java is platform-independent Java is safe";
        String[] words = text.split(" ");

        Map<String, Integer> wordCount = new HashMap<>();
        for (String word : words) {
            // merge: merge if key exists, add if not
            wordCount.merge(word, 1, Integer::sum);
        }
        System.out.println("Word frequency: " + wordCount);

        // putIfAbsent: add only if key is absent
        Map<String, String> config = new HashMap<>();
        config.put("host", "localhost");
        config.putIfAbsent("host", "remote-server"); // Already exists, ignored
        config.putIfAbsent("port", "8080");           // Absent, so added
        System.out.println("Config: " + config);

        // computeIfAbsent: cache pattern
        Map<Integer, String> cache = new HashMap<>();
        String result = cache.computeIfAbsent(42, key -> {
            System.out.println("Performing expensive computation...");
            return "result-" + key;
        });
        System.out.println("First call: " + result);

        // Second call: already cached, no computation
        String cached = cache.computeIfAbsent(42, key -> "new computation");
        System.out.println("Cache hit: " + cached);

        // TreeMap: auto-sorted by key
        Map<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("banana", 3);
        treeMap.put("apple", 5);
        treeMap.put("cherry", 1);
        System.out.println("TreeMap: " + treeMap); // Alphabetical order

        // Immutable Map creation
        Map<String, Integer> immutable = Map.of(
            "one", 1,
            "two", 2,
            "three", 3
        );
        System.out.println("Immutable Map: " + immutable);
    }
}

Practical Example: Phone Book

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PhoneBook {
    private final Map<String, List<String>> contacts = new HashMap<>();

    void addContact(String name, String phone) {
        contacts.computeIfAbsent(name, k -> new ArrayList<>()).add(phone);
        System.out.println("Added " + phone + " for " + name);
    }

    List<String> findByName(String name) {
        return contacts.getOrDefault(name, List.of());
    }

    void removeContact(String name) {
        if (contacts.remove(name) != null) {
            System.out.println(name + " removed");
        } else {
            System.out.println(name + " not found");
        }
    }

    void printAll() {
        System.out.println("=== Phone Book ===");
        contacts.forEach((name, phones) -> {
            System.out.println(name + ": " + String.join(", ", phones));
        });
        System.out.println("Total " + contacts.size() + " contacts");
    }

    Map<String, Integer> getStatistics() {
        Map<String, Integer> stats = new HashMap<>();
        stats.put("Total contacts", contacts.size());
        stats.put("Total phone numbers", contacts.values().stream()
                .mapToInt(List::size).sum());
        return stats;
    }

    public static void main(String[] args) {
        PhoneBook phoneBook = new PhoneBook();

        phoneBook.addContact("Alice", "010-1234-5678");
        phoneBook.addContact("Alice", "02-999-0000");  // Same name, different number
        phoneBook.addContact("Bob", "010-9876-5432");
        phoneBook.addContact("Charlie", "010-5555-3333");

        phoneBook.printAll();

        System.out.println("\nAlice's numbers: " + phoneBook.findByName("Alice"));
        System.out.println("Statistics: " + phoneBook.getStatistics());
    }
}

Today’s Exercises

  1. Find Duplicate Characters: Classify characters in a string into duplicate and unique sets. Input: "programming", Output: duplicates={g, r, m}, unique={p, o, a, i, n}.

  2. Student Grouping: Use Map<String, List<Student>> to group students by grade. Print the list of A-grade students, B-grade students, etc.

  3. English Dictionary: Implement an English dictionary using TreeMap. Create features for adding words, searching, retrieving a list of words starting with a specific letter (using subMap), and printing all words in alphabetical order.

Was this article helpful?